﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using BussinessLogicTecnoPez.AtencionCliente.Pedido;
using BussinessLogicTecnoPez.AtencionCliente.Cliente;
using BussinessLogicTecnoPez.Tipos_Comunes;
using BussinessLogicTecnoPez.Produccion.Producto;
using BussinessLogicTecnoPez.Produccion.Enfermedades_y_control_de_estanques;
using BussinessLogicTecnoPez;
using Tecnopez.Globals;
using BussinessLogicTecnoPez.Utils;

public partial class Modules_AtencionCliente_Pedido_ABMPedidos : System.Web.UI.Page
{
    private const string VIEW_STATE_ESTADO = "VIEW_STATE_ESTADO";
    private const string VIEW_STATE_EMPLEADO = "VIEW_STATE_EMPLEADO";

    private List<ItemDetallePedidoCliente> SessionDetallePedido
    {
        get { return Session["DetallePedido"] as List<ItemDetallePedidoCliente>; }
        set { Session["DetallePedido"] = value; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack == false)
        {
            SetMode(PageMode.ListMode);
            CargarComboCliente();

            rblPrioridad.Items.Clear();
            rblPrioridad.Items.Add(new ListItem(AppEnums.PedidoPrioridad.Alta.ToString(), Convert.ToInt32(AppEnums.PedidoPrioridad.Alta).ToString()));
            rblPrioridad.Items.Add(new ListItem(AppEnums.PedidoPrioridad.Media.ToString(), Convert.ToInt32(AppEnums.PedidoPrioridad.Media).ToString()));
            rblPrioridad.Items.Add(new ListItem(AppEnums.PedidoPrioridad.Baja.ToString(), Convert.ToInt32(AppEnums.PedidoPrioridad.Baja).ToString()));

            rblTipoEntrega.Items.Clear();
            rblTipoEntrega.Items.Add(new ListItem(AppEnums.PedidoTipoEntrega.Mostrador.ToString(), Convert.ToInt32(AppEnums.PedidoTipoEntrega.Mostrador).ToString()));
            rblTipoEntrega.Items.Add(new ListItem(AppEnums.PedidoTipoEntrega.Envio.ToString(), Convert.ToInt32(AppEnums.PedidoTipoEntrega.Envio).ToString()));
        }

        if (TPPProducto.ItemSelected != null)
        {
            FillProductPrice();
        }

        TPPCliente.ObjType = typeof(Cliente);
        TPPProducto.ObjType = typeof(Producto);
        TPPMoneda.ObjType = typeof(TipoMoneda);

        InicializarGrillas();     

        GenericMasterPage master = (GenericMasterPage)this.Master;
        master.Imagen = "../Styles/Icons/configurar.gif";
        master.Titulo = "Gestión de Pedidos";
        _lblError.Text = "";
    }
    private void FillProductPrice()
    {
        Producto objProducto = TPPProducto.ItemSelected as Producto;
        if (TPPCliente.ItemSelected == null)
        {
            txtPrecio.Text = objProducto.PrecioMinorista.ToString();
        }
        else
        {
            Cliente objCliente = TPPCliente.ItemSelected as Cliente;
            if (objCliente.TipoCliente != null)
            {
                if (objCliente.TipoCliente.IdTipoCliente == Convert.ToInt32( Functions.getConfiguration("tipoClienteMayorista")))
                {
                    txtPrecio.Text = objProducto.PrecioMayorista.ToString();
                }
                else
                {
                    txtPrecio.Text = objProducto.PrecioMinorista.ToString();
                }
            }
            else
            {
                txtPrecio.Text = objProducto.PrecioMinorista.ToString();
            }
        }
        
    }
    private void InicializarGrillas()
    {
        grdPedidos.setupGrid(typeof(Pedido), cargarGrilla, true, true, this.ViewState);

        DataControlField[] controlesExtra = new DataControlField[1];
        ButtonField b = new ButtonField();
        b.CommandName = "DeleteRow";
        //b.Text = "Eliminar";
        b.HeaderText = "Eliminar";
        b.ImageUrl = Functions.getHost(this.Page) + "Styles/Icons/eliminar.gif";
        b.ButtonType = ButtonType.Image;

        controlesExtra[0] = b;

        string[] strKeys = new string[1];
        strKeys[0] = "IdProducto";
        grdDetallePedido.DataKeyNames = strKeys;

        grdDetallePedido.setupGrid(typeof(ItemDetallePedidoCliente), cargarGrillaProductos, true, false, ViewState, controlesExtra);
    }

    private void SetMode(PageMode mode)
    {
        ViewState["PageMode"] = mode;
        switch (mode)
        {
            case PageMode.ListMode:
                mvABM.ActiveViewIndex = 0;
                break;
            case PageMode.NewMode:
                mvABM.ActiveViewIndex = 1;
                
                txtId.ReadOnly = true;
                TPPCliente.Enable = true;
                TPCFechaEmision.Enabled = true;
                TPCFechaEntrega.Enabled = true;
                rblPrioridad.Enabled = true;
                rblTipoEntrega.Enabled = true;
                TPPMoneda.Enable = true;
                txtMonto.ReadOnly = true;
                
                TPPProducto.Enable = true;
                txtCantidad.ReadOnly = false;
                txtPrecio.ReadOnly = false;
                cmdAgregarDetalle.Enabled = true;

                cmdAceptar.Visible = true;
                cmdCancelar.Enabled = true;
                cmdEditar.Enabled = false;
                cmdEliminar.Enabled = false;
                break;
            case PageMode.EditMode:
                mvABM.ActiveViewIndex = 1;

                txtId.ReadOnly = true;
                TPPCliente.Enable = true;
                TPCFechaEmision.Enabled = true;
                TPCFechaEntrega.Enabled = true;
                rblPrioridad.Enabled = true;
                rblTipoEntrega.Enabled = true;
                TPPMoneda.Enable = true;
                txtMonto.ReadOnly = true;

                TPPProducto.Enable = true;
                txtCantidad.ReadOnly = false;
                txtPrecio.ReadOnly = false;
                cmdAgregarDetalle.Enabled = true;

                cmdAceptar.Visible = true;
                cmdCancelar.Enabled = true;
                cmdEditar.Enabled = false;
                cmdEliminar.Enabled = false;
                break;
            case PageMode.ViewMode:
                mvABM.ActiveViewIndex = 1;

                txtId.ReadOnly = true;
                TPPCliente.Enable = false;
                TPCFechaEmision.Enabled = false;
                TPCFechaEntrega.Enabled = false;
                rblPrioridad.Enabled = false;
                rblTipoEntrega.Enabled = false;
                TPPMoneda.Enable = false;
                txtMonto.ReadOnly = true;

                TPPProducto.Enable = false;
                txtCantidad.ReadOnly = true;
                txtPrecio.ReadOnly = true;
                cmdAgregarDetalle.Enabled = false;

                cmdAceptar.Visible = false;
                cmdCancelar.Enabled = true;
                cmdEditar.Enabled = true;
                cmdEliminar.Enabled = true;
                break;
        }
    }

    private void cargarGrilla()
    {
        Pedido.getManager.ClearFilters();
        Pedido.getManager.ClearOrders();
        Pedido.getManager.AddFilter("idPedido", GenericManager<Pedido>.filterOperator.Like, "%" + txtBuscarCodigo.Text.Trim() + "%");

        if (ddlCliente.SelectedValue != "-1")
            Pedido.getManager.AddFilter("Cliente", GenericManager<Pedido>.filterOperator.Equals, ddlCliente.SelectedValue);

        if (ViewState[grdPedidos.PageDataViewOrderKey] == null)
        {
            Pedido.getManager.AddOrder("idPedido", GenericManager<Pedido>.Order.orderDirection.DESC);
        }
        else
        {
            Pedido.getManager.AddOrder(ViewState[grdPedidos.PageDataViewOrderKey].ToString(), (GenericManager<Pedido>.Order.orderDirection)ViewState[grdPedidos.PageDataViewOrdenDireccionKey]);
        }

        List<Pedido> lista = new List<Pedido>();
        lista = Pedido.getManager.GetFilter();
        grdPedidos.DataSource = lista;
        grdPedidos.DataBind();

    }

    private void CargarComboCliente()
    {
        ddlCliente.DataTextField = "RazonSocial";
        ddlCliente.DataValueField = "idCliente";
        ddlCliente.DataSource = Cliente.getManager.GetAll();
        ddlCliente.DataBind();

        ListItem item = new ListItem("Seleccione...", "-1");
        ddlCliente.Items.Insert(0, item);
    }

    protected void cmdNuevo_Click(object sender, EventArgs e)
    {
        SetMode(PageMode.NewMode);
        txtId.Text = "";
        TPPCliente.ItemSelected = null;
        TPCFechaEmision.Text = "";
        TPCFechaEntrega.Text = "";
        rblPrioridad.SelectedIndex = 0;
        rblTipoEntrega.SelectedIndex = 0;
        TPPProducto.ItemSelected = null;
        txtCantidad.Text = "";
        txtPrecio.Text = "";
        txtMonto.Text = "0";

        TipoEstadoPedido objEstado;
        TipoEstadoPedido.getManager.AddFilter("IDTIPOESTADOPEDIDO", GenericManager<TipoEstadoPedido>.filterOperator.Equals, Convert.ToInt32(TipoEstadoPedido.TiposEstadosPedidos.PendienteArmar));
        objEstado = TipoEstadoPedido.getManager.GetOne();
        if (objEstado != null)
        {
            lblEstado.Text = objEstado.Descripcion;
            ViewState[VIEW_STATE_ESTADO] = objEstado;
        }
        else
        {
            lblEstado.Text = "";
            ViewState[VIEW_STATE_ESTADO] = null;
        }

        Empleado objEmpledo;
        objEmpledo = Functions.getEmpleadoLogueado(this.Page);
        if (objEmpledo != null)
        {
            lblEmpleado.Text = objEmpledo.ToString();
            ViewState[VIEW_STATE_EMPLEADO] = objEmpledo;
        }
        else
        {
            lblEmpleado.Text = "";
            ViewState[VIEW_STATE_EMPLEADO] = null;
        }

        TipoMoneda objMoneda = Functions.getMonedaDefault();
        TPPMoneda.ItemSelected = objMoneda;

        this.SessionDetallePedido = null;
    }
    protected void cmdEditar_Click(object sender, EventArgs e)
    {
        SetMode(PageMode.EditMode);
    }
    protected void cmdEliminar_Click(object sender, EventArgs e)
    {
        try
        {
            Pedido objPedido;
            Pedido.getManager.ClearFilters();
            Pedido.getManager.AddFilter("IDPEDIDO", GenericManager<Pedido>.filterOperator.Equals, Convert.ToInt32(txtId.Text));
            objPedido = Pedido.getManager.GetOne();

            TipoEstadoPedido.getManager.ClearFilters();
            TipoEstadoPedido.getManager.AddFilter("IDTIPOESTADOPEDIDO", GenericManager<TipoEstadoPedido>.filterOperator.Equals, Convert.ToInt32(TipoEstadoPedido.TiposEstadosPedidos.Anulado));
            TipoEstadoPedido objEstado = TipoEstadoPedido.getManager.GetOne();
            objPedido.TipoEstadoPedido = objEstado;

            if (!Pedido.getManager.Update(objPedido))
                throw Pedido.getManager.GeneratedException;

            SetMode(PageMode.ListMode);
            cargarGrilla();
            this.SessionDetallePedido = null;
        }
        catch (Exception ex)
        {
            this._lblError.Text = ex.Message;
        }
    }
    protected void cmdAceptar_Click(object sender, EventArgs e)
    {
        try
        {
            Pedido objPedido = new Pedido();

            objPedido.Empleado = ViewState[VIEW_STATE_EMPLEADO] as Empleado;
            objPedido.TipoEstadoPedido = ViewState[VIEW_STATE_ESTADO] as TipoEstadoPedido;
            objPedido.Prioridad = Convert.ToInt32(rblPrioridad.SelectedValue);
            objPedido.TipoEntrega = Convert.ToInt32(rblTipoEntrega.SelectedValue);
            
            DateTime auxDate;
            if (!DateTime.TryParse(TPCFechaEmision.Text, out auxDate))
            {
                this._lblError.Text = "Fecha Emisión no posee el formato correcto.";
                return;
            }
            else
                objPedido.FechaEmision = auxDate;

            if (!DateTime.TryParse(TPCFechaEntrega.Text, out auxDate))
            {
                this._lblError.Text = "Fecha Emisión no posee el formato correcto.";
                return;
            }
            else
                objPedido.FechaEntrega = auxDate;

            if (TPPMoneda.ItemSelected != null)
            {
                TipoMoneda objMoneda = new TipoMoneda();
                objMoneda = (TipoMoneda)TPPMoneda.ItemSelected;
                objPedido.TipoMoneda = objMoneda;
                objMoneda = null;
            }

            decimal aux;
            if (!decimal.TryParse(txtMonto.Text, out aux))
            {
                this._lblError.Text = "Formato de monto incorrecto";
                return;
            }
            else
                objPedido.Monto = aux;

            if (TPPCliente.ItemSelected != null)
            {
                Cliente objCliente = new Cliente();
                objCliente = (Cliente)TPPCliente.ItemSelected;
                objPedido.Cliente = objCliente;
                objCliente = null;
            }

            objPedido.DetallePedido = this.GetDetalle();

            if (getMode() == PageMode.NewMode)
            {
                if (Pedido.getManager.Insert(objPedido) != true)
                {
                    throw Pedido.getManager.GeneratedException;
                }
                SetMode(PageMode.ListMode);
                cargarGrilla();
            }
            else
            {
                objPedido.IdPedido = int.Parse(txtId.Text.Trim());
                if (Pedido.getManager.Update(objPedido) != true)
                {
                    throw Pedido.getManager.GeneratedException;
                }
                SetMode(PageMode.ViewMode);
            }
        }
        catch (Exception exc)
        {
            _lblError.Text = "error: No se pudo realizar la operación";
            Functions.LogError(exc);
        }
    }
    private PageMode getMode()
    {
        if (ViewState["PageMode"] == null)
            return PageMode.ModeNotFound;
        return (PageMode)ViewState["PageMode"];
    }
    protected void cmdCancelar_Click(object sender, EventArgs e)
    {
        SetMode(PageMode.ListMode);
        this.SessionDetallePedido = null;
    }
    protected void cmdAgregarDetalle_Click(object sender, EventArgs e)
    {
        ItemDetallePedido item = new ItemDetallePedido();
        try
        {
            item.Producto = TPPProducto.ItemSelected as Producto;

            decimal auxCantidad;
            if (!decimal.TryParse(txtCantidad.Text, out auxCantidad))
            {
                this._lblError.Text = "Cantidad no posee el formato correcto.";
                return;
            }
            else
                item.Cantidad = auxCantidad;

            decimal aux;
            if (!decimal.TryParse(txtPrecio.Text, out aux))
            {
                this._lblError.Text = "Precio no posee el formato correcto.";
                return;
            }
            else
                item.Precio = aux;

            List<ItemDetallePedidoCliente> lista = this.SessionDetallePedido;
            if (lista == null)
                lista = new List<ItemDetallePedidoCliente>();

            foreach (ItemDetallePedidoCliente objItem in lista)
            {
                if (objItem.IdProducto == item.IdProducto)
                    throw new BussinessLogicTecnoPezException("El producto ya ha sido agregado.");
            }

            lista.Add(new ItemDetallePedidoCliente(item));
            this.SessionDetallePedido = lista;

            cargarGrillaProductos();

            TPPProducto.ItemSelected = null;
            txtCantidad.Text = "";
            txtPrecio.Text = "";

            _lblError.Text = "";

            CalcularTotal();
        }
        catch (BussinessLogicTecnoPezException exc)
        {
            _lblError.Text = exc.Message;
            Functions.LogError(exc);
        }
        catch (FormatException exc)
        {
            _lblError.Text = "Error de formato. Verifique los datos ingresados.";
            Functions.LogError(exc);
        }
        catch (Exception exc)
        {
            _lblError.Text = "error: No se pudo realizar la operación";
            Functions.LogError(exc);
        }
    }

    private void CalcularTotal()
    {
        List<ItemDetallePedidoCliente> objDetalle = this.SessionDetallePedido;
        if (objDetalle == null)
        {
            txtMonto.Text = "0";
            return;
        }
        decimal decTotal = 0;
        foreach (ItemDetallePedidoCliente objItem in objDetalle)
        {
            decTotal += objItem.Precio * objItem.Cantidad;
        }
        txtMonto.Text = decTotal.ToString();
    }

    private void cargarGrillaProductos()
    {
        List<ItemDetallePedidoCliente> lista = this.SessionDetallePedido;
        if (lista == null)
            grdDetallePedido.DataSource = null;
        else
            grdDetallePedido.DataSource = lista;
        grdDetallePedido.DataBind();
    }
    protected void grdDetallePedido_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (grdDetallePedido.Rows[0].Cells[0].Text == "&nbsp;")
        {
            return;
        }
        if (e.CommandName == "DeleteRow")
        {
            List<ItemDetallePedidoCliente> objDetalle = this.SessionDetallePedido;
            try
            {
                if (objDetalle == null)
                    return;

                Int32 indice = Convert.ToInt32(e.CommandArgument);
                this.SessionDetallePedido.RemoveAt(indice);

                _lblError.Text = "";

                cargarGrillaProductos();
                CalcularTotal();
            }
            catch (Exception ex)
            {
                _lblError.Text = ex.Message;
            }
            finally
            {
                cargarGrillaProductos();
            }
        }
    }
    protected void grdPedidos_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (grdPedidos.Rows[0].Cells[0].Text == "&nbsp;")
        {
            return;
        }

        if (e.CommandName == "ver")
        {
            int IdPedido = int.Parse(grdPedidos.DataKeys[System.Convert.ToInt32(e.CommandArgument)].Value.ToString());
            Pedido.getManager.ClearFilters();
            Pedido.getManager.AddFilter("IDPedido", GenericManager<Pedido>.filterOperator.Equals, IdPedido);
            Pedido objPedido = Pedido.getManager.GetOne();

            txtId.Text = objPedido.IdPedido.ToString();
            TPPCliente.ItemSelected = objPedido.Cliente;
            lblEstado.Text = objPedido.TipoEstadoPedido.ToString();
            lblEmpleado.Text = objPedido.Empleado.ToString();
            TPCFechaEmision.Text = objPedido.FechaEmision.ToShortDateString();
            TPCFechaEntrega.Text = objPedido.FechaEntrega.ToShortDateString();
            rblPrioridad.SelectedValue = objPedido.Prioridad.ToString();
            rblTipoEntrega.SelectedValue = objPedido.TipoEntrega.ToString();
            TPPMoneda.ItemSelected = objPedido.TipoMoneda;
            txtMonto.Text = objPedido.Monto.ToString();

            this.SessionDetallePedido = GetListItems(objPedido.DetallePedido);
            cargarGrillaProductos();

            SetMode(PageMode.ViewMode);

            if (objPedido.TipoEstadoPedido.IdTipoEstadoPedido == Convert.ToInt32(TipoEstadoPedido.TiposEstadosPedidos.Anulado))
            {
                cmdEliminar.OnClientClick = "alert('Al pedido ya ha sido anulado'); return false";
                cmdEditar.OnClientClick = "alert('Solo pueden editarse pedidos en estado Pendientes de Armar'); return false";
            }
            else
            {
                if (objPedido.TipoEstadoPedido.IdTipoEstadoPedido == Convert.ToInt32(TipoEstadoPedido.TiposEstadosPedidos.PendienteArmar))
                {
                    cmdEliminar.OnClientClick = "if (!confirm('Desea anular el pedido?')){return false;}";
                    cmdEditar.OnClientClick = "";
                }
                else
                {
                    cmdEliminar.OnClientClick = "alert('Solo pueden editarse pedidos en estado Pendientes de Armar'); return false";
                    cmdEditar.OnClientClick = "alert('Solo pueden editarse pedidos en estado Pendientes de Armar'); return false";
                }
            }
        }
    }
    private List<ItemDetallePedidoCliente> GetListItems(DetallePedido objDetalle)
    {
        if (objDetalle == null || objDetalle.ItemList == null || objDetalle.ItemList.Count <= 0)
            return null;

        List<ItemDetallePedidoCliente> objList = new List<ItemDetallePedidoCliente>();
        ItemDetallePedidoCliente objItemDetalle;
        foreach (ItemDetallePedido objItem in objDetalle.ItemList)
        {
            objItemDetalle = new ItemDetallePedidoCliente(objItem);
            objList.Add(objItemDetalle);
        }
        return objList;
    }

    private DetallePedido GetDetalle()
    {
        if (this.SessionDetallePedido == null || this.SessionDetallePedido.Count <= 0)
            throw new Exception("El pedido debe incluir al menos un item");

        DetallePedido objDetalle = new DetallePedido();
        foreach (ItemDetallePedidoCliente objItem in this.SessionDetallePedido)
        {
            objDetalle.add(objItem.ItemDetalle);
        }
        return objDetalle;
    }
}

internal class ItemDetallePedidoCliente
{
    private ItemDetallePedido objItem;

    public ItemDetallePedidoCliente(ItemDetallePedido objItem)
    {
        this.objItem = objItem;
    }

    public ItemDetallePedido ItemDetalle
    {
        get { return objItem; }
    }

    [FriendlyName("Producto", true)]
    public Producto Producto
    {
        get { return objItem.Producto; }            
    }

    [FriendlyName("IdProducto", false)]
    public int IdProducto
    {
        get { return objItem.Producto.IdProducto; }
    }

    [FriendlyName("Cantidad", true)]
    public decimal Cantidad
    {
        get { return objItem.Cantidad; }
    }

    [FriendlyName("Precio", true)]
    public decimal Precio
    {
        get { return objItem.Precio; }
    }
}
